package cn.skter.common.ffmpeg;

import it.sauronsoftware.jave.Encoder;
import it.sauronsoftware.jave.EncoderException;
import it.sauronsoftware.jave.MultimediaInfo;
import it.sauronsoftware.jave.VideoInfo;
import lombok.extern.slf4j.Slf4j;
import org.bytedeco.ffmpeg.global.avcodec;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.FFmpegFrameRecorder;
import org.bytedeco.javacv.Frame;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;

/***
 * @ClassName FFmpegUtil
 * @Author Eureka
 * @Description // ffmpeg工具类
 * @Date 2022/4/27 14:42
 * @Version V1.0
 **/
@Slf4j
public class FFmpegUtil {

    /***
     * @Description // 判断视频文件是否为H264
     **/
    public static boolean isH264(String videoPath) {
        File file = new File(videoPath);
        Encoder encoder = new Encoder();
        try {
            MultimediaInfo info = encoder.getInfo(file);
            VideoInfo video = info.getVideo();
            String decoder = video.getDecoder();
            if (decoder.equals("h264")) {
                return true;
            } else {
                return false;
            }
        } catch (EncoderException e) {
            //e.printStackTrace();
            return false;
        }
    }

    /**
     * ffmpeg -i test.h265 video.mp4
     * ffmpeg的h265转h264格式的mp4
     *
     * @param videoPath  视频地址
     * @param targetPath 目标地址
     * @throws IOException
     */
    public static void ffToMp4(String ffmpegPath, String videoPath, String targetPath) throws IOException {
        //String path = System.getProperty("user.dir") + File.separator + "ffmpeg-5.0.1" + File.separator + "bin" + File.separator + "ffmpeg.exe";
        ProcessBuilder processBuilder = new ProcessBuilder(ffmpegPath, "-y",
                "-i", videoPath,
                targetPath);
        processBuilder.redirectErrorStream(true);
        Process process = processBuilder.start();
        StringBuilder processOutput = new StringBuilder();
        try (BufferedReader processOutputReader = new BufferedReader(
                new InputStreamReader(process.getInputStream()));) {
            String readLine;
            while ((readLine = processOutputReader.readLine()) != null) {
                processOutput.append(readLine + System.lineSeparator());
            }
            process.waitFor();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            if (process != null) {
                process.destroy();
            }
        }

        String[] str = processOutput.toString().trim().split("\n");
        String[] res = new String[3];
        System.arraycopy(str, str.length - 3, res, 0, 3);
        log.info("ffmpegConvert2Mp4 res: {}", String.join("\n", Arrays.asList(res)));
    }

    /**
     * FFmpegFrameGrabber转换h265视频文件为h265的mp4
     *
     * @param videoPath  视频地址
     * @param targetPath 目标地址
     * @return
     */
    public static void fffgToMp4(String videoPath, String targetPath) {
        File file = new File(videoPath);
        FFmpegFrameGrabber frameGrabber = new FFmpegFrameGrabber(file);
        Frame captured_frame = null;
        FFmpegFrameRecorder recorder = null;
        try {
            frameGrabber.start();
            recorder = new FFmpegFrameRecorder(targetPath, frameGrabber.getImageWidth(), frameGrabber.getImageHeight(), frameGrabber.getAudioChannels());
            // 视频编码//avcodec.AV_CODEC_ID_H264  //AV_CODEC_ID_MPEG4
            recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
            // 视频质量
            recorder.setVideoQuality(25);
            // 视频格式
            recorder.setFormat("mp4");
            recorder.setFrameRate(frameGrabber.getFrameRate());
            //recorder.setSampleFormat(frameGrabber.getSampleFormat()); //
            recorder.setSampleRate(frameGrabber.getSampleRate());
            recorder.setAudioChannels(frameGrabber.getAudioChannels());
            recorder.setFrameRate(frameGrabber.getFrameRate());
            recorder.start();
            while ((captured_frame = frameGrabber.grabFrame()) != null) {
                try {
                    recorder.setTimestamp(frameGrabber.getTimestamp());
                    recorder.record(captured_frame);

                } catch (Exception e) {
                }
            }
            recorder.stop();
            recorder.release();
            frameGrabber.stop();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
